#include <stdint.h>
#include <string.h>

#include "u8a.h"

U8a_len
u8a_ahead_len(const char *str)
{
	unsigned char c = *str;
	U8a_len len = 0;

	for (; c >> 7; ++len, c <<= 1);

	if (!len)
		return 1;

	return len;
}

/* #include <stdio.h> */

/* static void */
/* print_bits(char c) */
/* { */
/* 	int i = 0; */

/* 	for (; i < 8; ++i) */
/* 		printf("%d", !!((c << i) & 0x80)); */

/* 	printf("\n"); */
/* } */

U8a_len
u8a_back_len(const char *str)
{
	U8a_len len = 1;
	unsigned char c = ((unsigned char) *--str) >> 6;

	if (!(c >> 1))
		return 1;

	for (; c == 2; ++len, c = ((unsigned char) *--str) >> 6);

	return len;
}

U8a_len
u8a_unit_len(U8a_unit unit)
{
	return u8a_ahead_len((char *) &unit);
}

size_t
u8a_units_size_capped(const char *str, int max_units, size_t rest)
{
	U8a_len unit_len;
        size_t len = 0;

	for (; max_units && rest;
	     --max_units, rest -= unit_len, len += unit_len)
		unit_len = u8a_ahead_len(str + len);

	return len;
}

size_t
u8a_units_size(const char *str, size_t rest)
{
	U8a_len unit_len;
        size_t len = 0;

	for (; rest; rest -= unit_len, len += unit_len)
		unit_len = u8a_ahead_len(str + len);

	return len;
}

size_t
u8a_units(const char *str, size_t rest)
{
	U8a_len unit_len;
        size_t len = 0;
	size_t cnt = 0;

	for (; rest; rest -= unit_len, len += unit_len, ++cnt)
		unit_len = u8a_ahead_len(str + len);

	return cnt;
}

U8a_unit
u8a_get_unit(const char *str, U8a_len *len)
{
	U8a_unit unit = 0;

        *len = u8a_ahead_len(str);
	memcpy(&unit, str, *len);
	return unit;
}
